home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / gle / util / letz / polish.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-29  |  10.2 KB  |  399 lines

  1. char *un_quote();
  2. char *ns[3] = {"Nothing","Number","String"};
  3. extern int gle_debug;
  4. /*---------------------------------------------------------------------------*/
  5. #include "all.h"
  6.  
  7. #include <math.h>
  8. int add_strvar(char *pcode,int *plen,int i);
  9. int ngerror;
  10. int token_norm(void);
  11. int token_space(void);
  12.  
  13. #define true (!false)
  14. #define false 0
  15. #define tok(n)  tk[n]
  16. #define abort goto fatal_err
  17. /*---------------------------------------------------------------------------*/
  18. /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
  19. #define stack_bin(i,p)     stack_op(pcode,plen,stk,stkp,&nstk,i-10+(last_typ*20),p+curpri)
  20. #define stack_fn(i)     stack_op(pcode,plen,stk,stkp,&nstk,i,10+curpri)
  21. #define dbg if ((gle_debug & 4)>0)
  22. /*---------------------------------------------------------------------------*/
  23. /* Input is token array, and pointer to current point, output is pcode */
  24.  
  25. /* typedef struct op_key (*OPKEY)[100];  */
  26. /* typedef char (*(*TOKENS)[500]); */
  27.  
  28. int zpolish(TOKENS tk,int *ntok,int *curtok,char *pcode,int *plen,int *rtype);
  29. polish(char *expr,char *pcode,int *plen,int *rtype)
  30. {
  31. static char inbuff[200];
  32. static char *tk[500];
  33. static char tkbuff[500];
  34. static int ntk,ct;
  35. char *space_str=" ";
  36.     static char buff[50];
  37.     static int start_token;
  38.     double xxx;
  39.     int idx,ret,np,*plist,saveplen,term_bracket;
  40.     int curpri=0;
  41.     int i,j,v,p,savelen,isa_string,not_string,last_typ;
  42.     int nstk=0,stk[50],stkp[50];    /* stack for operators */
  43.     int unary=1;        /* binary or unary operation expected */
  44.     int ln;            /* length of current token */
  45.     char *cts;        /* current token */
  46.     /* last_typ, 1=number,2=string */
  47.  
  48.     *plen = 0;
  49.     if (tk[400]==NULL) for (i=0;i<500;i++) tk[i] = space_str;
  50.     isa_string = false;
  51.     not_string = false;
  52.     if (*rtype==1) not_string = true;
  53.     /* if (*rtype==2) isa_string = true; */
  54.     *plen = *plen*4;    /* change into byte count */
  55.     if (*rtype>0) term_bracket = true;
  56.     last_typ = *rtype;
  57.     saveplen = *plen;
  58.  
  59.     add_i(pcode,plen,1);    /* expression follows */
  60.     savelen = *plen;    /* Used to set acutal length at end */
  61.     add_i(pcode,plen,0);    /* Length of expression */
  62.     dbg gprint("====Start of expression {%s} \n",expr);
  63.     if (strlen(expr)==0) {gprint("Zero length expression\n"); return;}
  64.     if (!start_token) {
  65.         ntk = 0; ct=1;
  66.         token_norm();
  67.         token(expr,tk,&ntk,tkbuff);
  68.         token_space();
  69.     }
  70.     for (;;) {
  71.       cts = tok(ct);
  72.       dbg gprint("First word token=%d via (1=unary %d) cts {%s} %d \n "
  73.         ,ct,unary,cts,strlen(cts));
  74.       ln = strlen(cts);
  75.        switch (unary) {
  76.       case 1:  /* a unary operator, or function, or number or variable */
  77.         if (ln==1 && (*cts=='E')) goto notnumber;
  78.         if (ln==1 && (*cts=='-')) goto notnumber;
  79.         if (isnumber(cts))  {
  80. evalagain:            dbg gprint("Found number {%s}\n",cts);
  81.             if (lastchar(cts,'E'))  {
  82.                 strcpy(buff,cts);
  83.                 strcat(buff,tok(++ct));
  84.                 if (*tok(ct)=='-') {
  85.                     strcat(buff,tok(++ct));
  86.                 }
  87.                 tok(ct) = buff;
  88.                 cts = tok(ct);
  89.                 goto evalagain;
  90.             }
  91.             xxx = atof(cts);
  92.             add_f(pcode,plen,xxx);
  93.             if (last_typ==2) gprint("Expecting string {%s} \n",cts);
  94.             last_typ = 1;
  95.             unary=2; break;
  96.         }
  97. notnumber:    /* NOT a number, Is it a built in function */
  98.         /* int idx,ret,np,*plist; */
  99.         find_un(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  100.         if (idx>63) {
  101.           dbg gprint("Found built in function \n");
  102.             if (*tok(++ct)!='(') {
  103.                 gprint("Expecting left bracket after functsion name");
  104.                 abort;
  105.             }
  106.             {
  107.              char fcode[400];
  108.              char *fp;
  109.              int flen,vtype,nparam=0;
  110.              if (*tok(ct+1)!=')') {
  111.                while (*tok(ct)!=')') {
  112.                 nparam++;
  113.                 vtype = *(plist+nparam-1);
  114.                 flen = 0;
  115.                 (ct)++;
  116.                 start_token = true;
  117.                 polish("xx",fcode,&flen,&vtype);
  118.                 start_token = false;
  119.                 flen = flen * 4;
  120.                 if (nparam>np) {gprint("Too many paramters got=%d want=%d \n",nparam,np);abort;}
  121.                 if (vtype==0) abort;
  122.                 add_pcode(pcode,plen,fcode,&flen);
  123.                }
  124.              } else {
  125.                 ct++;
  126.              }
  127.             }
  128.             if (last_typ==(3-ret)) {
  129.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  130.                 abort;
  131.             }
  132.             last_typ = ret;
  133.             add_fn(pcode,plen,idx);
  134.             unary = 2; break;
  135.         } else if (idx>0) {
  136.             stack_fn(idx);
  137.             unary=1; break;
  138.         }
  139.  
  140.          /* Is it a user-defined function, identical code too above. */
  141.           sub_find(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  142.           if (idx>0) {
  143.           dbg gprint("Found user function \n");
  144.             if (*tok(++ct)!='(') {
  145.                 gprint("Expecting left bracket after function name");
  146.                 abort;
  147.             }
  148.             {
  149.             char fcode[400];
  150.             char *fp;
  151.             int flen,nnn,vtype,nparam=0;
  152.             if (*tok(ct+1)!=')') {
  153.              while (*tok(ct)!=')') {
  154.                 ct++;
  155.                 nparam++;
  156.                 vtype = *(plist+nparam-1);
  157.                 nnn = *(plist+nparam);
  158.                 flen = 0;
  159.                 start_token = true;
  160.                 polish("xx",fcode,&flen,&vtype);
  161.                 start_token = false;
  162.                 flen = flen * 4;
  163.                 if (nparam>np) {gprint("Too many U paramters got=%d want=%d \n",nparam,np);abort;}
  164.                 if (vtype==0) abort;
  165.                 add_pcode(pcode,plen,fcode,&flen);
  166.               }
  167.              } else {
  168.                 ct++;
  169.              }
  170.             }
  171.             if (last_typ==(3-ret)) {
  172.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  173.                 abort;
  174.             }
  175.             if (ret>0 && ret<3) last_typ = ret;
  176.             add_fn(pcode,plen,idx+200);
  177.             unary = 2; break;
  178.         } else if (idx>0) {
  179.             stack_fn(idx);
  180.             unary=1; break;
  181.         }
  182.  
  183.  
  184.         /* Is it a 'known' variable */
  185.         var_find(cts,&v,&ret);
  186.         if (v>=0) {
  187.             dbg gprint("Found variable %d \n",v);
  188.             if (last_typ==(3-ret)) {
  189.                 gprint("Expecting {%s} \n",ns[last_typ]);
  190.                 abort;
  191.             }
  192.             last_typ=ret;
  193.             if (ret==2) add_strvar(pcode,plen,v);
  194.             else add_var(pcode,plen,v);
  195.             unary=2; break;
  196.         }
  197.         /* Is it a atring */
  198.         if (*cts=='"') {
  199.           dbg gprint("Found string \n");
  200.             if (last_typ==1) {
  201.                 gprint("Expecting number {%s} \n",cts);
  202.                 abort;
  203.             }
  204.             last_typ = 2;
  205.             add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  206.             unary = 2; break;
  207.         }
  208.         if (*cts=='(') { curpri = curpri + 100; break; }
  209.         if (*cts==')') {
  210.             if (curpri>0) {
  211.                 curpri = curpri - 100;
  212.                 unary = 2; break;
  213.             }
  214.             gprint("Too many right brackets found in exp \n");
  215.  
  216.         }
  217.         /* must be unquoted string, unless a binary operator
  218.         was found, in which case it is an undelcared variable */
  219.         if (not_string) {
  220.             dbg gprint("Found un-initialized variable {%s} /n",cts);
  221.             var_add(cts,&v,&ret);
  222.             last_typ=ret;
  223.             add_var(pcode,plen,v) ;
  224.             unary=2;
  225.             break;
  226.         }
  227.         last_typ = 2;
  228.         dbg printf("Unquoted string (%s) \n",cts);
  229.         add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  230.         isa_string = true;
  231.         unary = 2; break;
  232.         isa_string = true;
  233.         add_string(pcode,plen,cts);
  234.         unary = 2;  /* Expecting end of expression next !! */
  235.         break;
  236.       case 2:  /* a binary operator, or space, or end of line */
  237.         if (ct>ntk || *cts==' ' || *cts==',' ) {
  238.             goto end_expression;
  239.         }
  240.         if (*cts==')' && curpri==0) {
  241.             goto end_expression;
  242.         }
  243. /* MIGHT (gives error with a$ = b$+c$) */
  244.         if (isa_string) {
  245.             gprint("Expression contained unquoted string\n");
  246.             abort;
  247.         }
  248.  
  249.         not_string = true;
  250.         /* Binary operators, +,-,*,/,^,<,>,<=,>=,.and.,.or. */
  251.         switch (*cts) {
  252.           case '+' : v = 1; p=2; break;
  253.           case '-' : v = 2; p=2; break;
  254.           case '*' : v = 3; p=3; break;
  255.           case '/' : v = 4; p=3; break;
  256.           case '^' : v = 5; p=4; break;
  257.           case '=' : v = 6; p=1; break;
  258.           case '<' : v = 7; p=1;
  259.             if (*tok(ct+1)=='=') {v=8;++ct;} break;
  260.           case '>' : v = 9;p=1;
  261.             if (*tok(ct+1)=='=') {v=10;++ct;} break;
  262.           case '.' : p=1;
  263.             if (strcmp(cts,".AND.")) {v=11;} break;
  264.             if (strcmp(cts,".OR.")) {v=12;} break;
  265.            default : v = 0 ; break;
  266.         }
  267.         if (v>0) {
  268.             if (last_typ<1 || last_typ > 3) last_typ = 1;
  269.             stack_bin(v,p);
  270.             dbg gprint("Found binary operator \n");
  271.             unary=1; break;
  272.         }
  273.         if (*cts==')') {
  274.             if (curpri>0) {
  275.                 curpri = curpri - 100;
  276.                 unary = 2; break;
  277.             }
  278.             if (term_bracket!=true) {
  279.                 gprint("Too many right brackets, expecting binary operator \n");
  280.                 abort;
  281.             }
  282.             goto end_expression;
  283.         }
  284.       }
  285.       if (++ct>ntk) { goto end_expression; }
  286. /*    gprint("Next token is {%s} \n",tok(ct)); */
  287.     }
  288. end_expression:
  289.     if (*tok(ct)==' ') (ct)++;
  290.     dbg gprint("Got expression , curtok=%d {%s} \n",ct,tok(ct));
  291.     *rtype = last_typ;
  292.       dbg gprint("Found END OF EXPRESSION \n");
  293.     if (!start_token) if (curpri!=0) {gprint("Missing right brackets");}
  294.     /* Pop everything off the stack */
  295.     for (i=nstk;i>0;i--) {
  296.         dbg gprint("Adding left over operators  I = %d  op=%d \n",i,stk[i]);
  297.         add_i(pcode,plen,stk[i]);
  298.     }
  299.     * ((long *) (pcode+savelen)) = (*plen - savelen)/4-1;  /* Set length of expression */
  300.     *plen = *plen/4;    /* change back to int count */
  301. return;
  302. fatal_err:
  303.         ngerror++;
  304.     gprint("Aborting expression parsing. \n");
  305.     *plen = saveplen;
  306.     *rtype = 0;
  307. }
  308.  
  309. /*------------------------------------------------------------------*/
  310. /* append fcode to pcode */
  311. add_pcode(char *pcode,int *plen,char *fcode,int *flen)
  312. {
  313.     char *p;
  314.     p = pcode + *plen;
  315.     memcpy(p,fcode,*flen);
  316.     *plen = *plen + *flen;
  317. }
  318. add_i(char *pcode,int *plen,long i)
  319. {
  320.     long *p;
  321.     p = (long *) (pcode + *plen);
  322.     *p = i;
  323.     *plen += 4;
  324. }
  325. add_f(char *pcode,int *plen,double f)
  326. {
  327.     union { double d ; long l[2]; short s[4]; } both;
  328.     both.d = f;
  329.     add_i(pcode,plen,2);
  330.     add_i(pcode,plen,both.l[0]);
  331.     add_i(pcode,plen,both.l[1]);
  332. }
  333. add_var(char *pcode,int *plen,int i)
  334. {
  335.     add_i(pcode,plen,3);
  336.     add_i(pcode,plen,i);
  337. }
  338. add_strvar(char *pcode,int *plen,int i)
  339. {
  340.     add_i(pcode,plen,4);
  341.     add_i(pcode,plen,i);
  342. }
  343. add_fn(char *pcode, int *plen, int i)
  344. {
  345.     add_i(pcode,plen,i);
  346.     dbg gprint(" add Function %d \n",i);
  347. }
  348. add_string(char *pcode, int *plen, char *s)
  349. {
  350.     char *p;
  351.     int sl;
  352.     dbg gprint("adding string {%s} \n",s);
  353.     add_i(pcode,plen,5);
  354.     sl = strlen(s)+1;
  355.     p = pcode + *plen;
  356.     sl = ((sl + 3) & 0xfffc);
  357.      strncpy(p,s,sl);
  358.     *plen = *plen + sl;
  359. }
  360. /*------------------------------------------------------------------*/
  361. /* Remove the quotes from a string and return a modified pointer */
  362. char *un_quote(char *cts)
  363. {
  364.     int i,j;
  365.     i = strlen(cts);
  366.     if (*cts=='"') {
  367.         *(cts+i-1) = 0;
  368.         cts = cts + 1;
  369.     }
  370.     return cts;
  371. }
  372. /*------------------------------------------------------------------*/
  373. stack_op(char *pcode, int *plen, int stk[]
  374.     , int stkp[], int *nstk,  int i, int p)
  375. {
  376.     dbg gprint("Stack oper %d priority %d \n",i,p);
  377.     while (p<=stkp[*nstk] &&(*nstk)>0) {
  378.         dbg gprint("ADDING oper stack = %d  oper=%d \n",*nstk,stk[(*nstk)]);
  379.         add_i(pcode,plen,stk[(*nstk)--]);
  380.     }
  381.     stk[++(*nstk)] = i;
  382.     stkp[*nstk] = p;
  383. }
  384. isnumber(char *s)
  385. {
  386.     while (*s!='\0') {
  387.         if (isdigit(*s) || *s=='.' || *s=='E' ) s++;
  388.         else  return false;
  389.     }
  390.     return true;
  391. }
  392. lastchar(char *s, char c)
  393. {
  394.     while (*s!='\0') {s++;}
  395.     return *(--s)==c;
  396. }
  397.  
  398.  
  399.